package com.example.demo.server;

import com.example.demo.code.CodeScore;
import com.example.demo.dao.DaoClass;
import com.example.demo.dao.DaoTestPaper;
import com.example.demo.dao.DaoUserTest;
import com.example.demo.pojo.Question;
import com.example.demo.pojo.StringXY;
import com.example.demo.pojo.TestPaper;
import com.example.demo.pojo.TestUser;
import com.example.demo.util.DateUtil;
import com.example.demo.util.FileUtil;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Service;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class QuestionSever {
    @Autowired
    DaoTestPaper daoTestPaper;
    @Autowired
    DaoClass daoClass;
    @Autowired
    DaoUserTest userTest;
    //前端传来的试题列表组成一个xml文档
   public String write2xml(List<Question> questionList){
        Element questions= new Element("questions");
       for (Question question : questionList){
           Element problem=new Element("problem");
           problem.addContent(new Element("name").setText(question.getContents()));
           problem.addContent(new Element("answer").setText(question.getAnswer()));
           problem.addContent(new Element("value").setText(question.getValue()+""));
           Element options=new Element("options");
           for(String s :question.getTestOptions()){
               options.addContent(new Element("string").setText(s));
           }
           problem.addContent(options);
           questions.addContent(problem);
       }
       Document doc = new Document(questions);
       //读取格式
       Format format = Format.getCompactFormat();
       format.setEncoding("UTF-8");
       //设置xml文件缩进4个空格
       format.setIndent("    ");
       //建一个xml输出工厂
       XMLOutputter xmlout = new XMLOutputter(format);
       String name= FileUtil.getRandomString(4)+DateUtil.getTimeStamp();
       try {
           FileOutputStream fileOutputStream= new FileOutputStream("E:\\代码\\ASP.net Web程序设计\\web程序设大作业\\后端\\workspace\\questions\\"+name+".xml");
           //将其写好的文本给工厂
           xmlout.output(doc, fileOutputStream);
           fileOutputStream.close();

       } catch (Exception e) {
           e.printStackTrace();
       }
       return name;
   }
   public void saveTestPaper(TestPaper testPaper){
       if(Objects.equals(testPaper.getTestId(), ""))
           testPaper.setTestId(FileUtil.getRandomString(8));
       testPaper.setType(0);
       testPaper.setClassName(daoClass.findByClassId(testPaper.getClassId()).getClassName());
       daoTestPaper.save(testPaper);
   }
    public List<TestPaper> getTestPaperByKey(String key,int index){
        Pageable pageable = PageRequest.of(index, 10);
        return daoTestPaper.findAllByClassNameContainingOrTestNameContaining(key,key,pageable).getContent();
    }
    public int countTestPaperByKey(String key){
        return daoTestPaper.countByClassNameContainingOrTestNameContaining(key,key);
    }
    //type=1时包括答案
    public List<Question> xml2List(String name,int type){
        List<Question> S=new ArrayList<>();
        SAXBuilder sb=new SAXBuilder();
        Document doc= null; //构造文档对象
        try {
            doc = sb.build("file:///" + "E:\\代码\\ASP.net Web程序设计\\web程序设大作业\\后端\\workspace\\questions\\" + name + ".xml");
            Element root = doc.getRootElement(); //获取根元素
            List<Element> list = root.getChildren("problem");
            for (Element value : list) {
                Question question=new Question();
                List<Element> list1 =value.getChild("options").getChildren("string");
                if(type==1)
                    question.setAnswer(value.getChildText("answer"));
                else
                    question.setAnswer("");
                question.setContents(value.getChildText("name"));
                question.setValue(new Integer(value.getChildText("value")));
                List<String> options=new ArrayList<>();
                for (Element value1 : list1)
                        options.add(value1.getText());
                question.setTestOptions(options);
                S.add(question);
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return S;

    }
    public void putStu(String id){
       TestPaper testPaper=daoTestPaper.findByTestId(id);
       testPaper.setType(1);
       daoTestPaper.save(testPaper);
    }
    public List<TestPaper> getTestPaperByKeyAndUser(String userId,String key,int index){
        Pageable pageable = PageRequest.of(index-1, 10);
        return daoTestPaper.getUserTest(key,userId,pageable).getContent();
    }
    public int removeById(String id){
       int code=200;
       try {
           daoTestPaper.deleteById(id);
       }
       catch (Exception e){
           e.printStackTrace();
       }
       return code;
    }
    public long countByName(String name,String userId){
       return daoTestPaper.countUserTest(name,userId);
    }
    public CodeScore getCodeScore(String testId, String userId){
       CodeScore codeScore =new CodeScore();
       codeScore.setCode(userTest.countByUserIdAndTestId(userId,testId));
       if(codeScore.getCode()>0)
           codeScore.setTestUser(userTest.findByUserIdAndTestId(userId,testId));
       return codeScore;

    }
    public TestPaper getTestById(String id){
       return  daoTestPaper.findByTestId(id);
    }
    public String answer2xml(List<String> answer){
        Element answer1= new Element("answer");
        for (String s : answer){
            Element problem=new Element("string");
            problem.setText(s);
            answer1.addContent(problem);
        }
        Document doc = new Document(answer1);
        //读取格式
        Format format = Format.getCompactFormat();
        format.setEncoding("UTF-8");
        //设置xml文件缩进4个空格
        format.setIndent("    ");
        //建一个xml输出工厂
        XMLOutputter xmlout = new XMLOutputter(format);
        String name= FileUtil.getRandomString(4)+DateUtil.getTimeStamp();
        try {
            FileOutputStream fileOutputStream= new FileOutputStream("E:\\代码\\ASP.net Web程序设计\\web程序设大作业\\后端\\workspace\\answer\\"+name+".xml");
            //将其写好的文本给工厂
            xmlout.output(doc, fileOutputStream);
            fileOutputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }
    public void uploadTestUser(TestUser testUser){
       List<Question> Q=xml2List(testUser.getTestFile(),1);
       testUser.setScore(0);
       List<String> A=getUserAnswer(testUser.getAnswerFile());
        for(int i=0;i<Q.size();i++) {
            if (Q.get(i).getAnswer().equals(A.get(i)))
                testUser.setScore(testUser.getScore() + Q.get(i).getValue());
        }
        testUser.setTypes(1);
        userTest.save(testUser);
    }
    public List<String> getUserAnswer(String name){
        SAXBuilder sb=new SAXBuilder();
        Document doc= null; //构造文档对象
        List<String> A=new ArrayList<>();
        try {
            doc = sb.build("file:///" + "E:\\代码\\ASP.net Web程序设计\\web程序设大作业\\后端\\workspace\\answer\\" + name + ".xml");
            Element root = doc.getRootElement(); //获取根元素
            List<Element> list = root.getChildren("string");
            for (Element value : list) {
                A.add(value.getText());
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return A;
    }
    //分组
    public List<Integer> countByScore(String testId,int k){
       int a=userTest.maxByTestId(testId);
       int m;
        List<Integer> S=new ArrayList<>();
       if(a%k==0) {
           m = a / k;
           for (int i = 0; i < m-1; i++)
               S.add(userTest.countAtoBByClassId(testId, k * i, k * (i + 1)));
           S.add(userTest.countAtoBByClassId(testId, k * (m-1), k * m + 1));
       }
       else {
           m = a / k + 1;
           for (int i = 0; i < m; i++)
               S.add(userTest.countAtoBByClassId(testId, k * i, k * (i + 1)));
       }
       return S;
    }

    public List<TestPaper> getAllTest(){
       return daoTestPaper.getAll();
    }
    public List <StringXY> getAllXYBy5(String testId){
       List<Integer> S=countByScore(testId,10);
       List<StringXY> M=new ArrayList<>();
       for(int i=0;i<S.size();i++){
           StringXY stringXY=new StringXY();
           stringXY.setX(i*10+"");
           stringXY.setY(S.get(i));
           M.add(stringXY);
       }
       return M;
    }
    public  List<StringXY> getAllXYInfo(String testId) {
        List<Integer> S = userTest.getAllScore(testId);
        List<StringXY> M=new ArrayList<>();
        M.add(new StringXY("最大值",userTest.maxByTestId(testId)));
        M.add(new StringXY("最小值",userTest.minByTestId(testId)));
        M.add(new StringXY("平均值",(float) userTest.sumByTestId(testId)/userTest.countByTestId(testId)));
        if(S.size()>0){
            if(S.size()%2==0)
                M.add(new StringXY( "中位数", (float) ((float)(S.get(S.size()/2-1)+S.get(S.size()/2))/2.0)));
            else
                M.add(new StringXY( "中位数", S.get(S.size()/2)));
            M.add(new StringXY( "众数",getZhongShu(S)));
        }
        else {
            M.add(new StringXY( "中位数",0));
            M.add(new StringXY( "众数",0));
        }

        return M;
    }

    public List<StringXY> getXYByStride(String testId,int stride){
       List<Integer> S=countByScore(testId,stride);
       List<StringXY> M=new ArrayList<>();
       for(int i=0;i<S.size();i++)
            M.add(new StringXY(i*stride+" ~ "+(i+1)*stride,S.get(i)));
       return M;

    }

    public int getZhongShu(List<Integer> S ){
       int count=1;
       int Num=S.get(0);
       int icount=1;
       for(int i=1;i<S.size();i++){
          if(Objects.equals(S.get(i), S.get(i - 1)))
              icount++;
          else
              icount=1;
          if(icount>count){
              count=icount;
              Num=S.get(i);
          }
       }
       return Num;

    }

}
